package managedbean.stakeholder;

import entity.AddressEntity;
import entity.FnBBranchEntity;
import entity.OperatingHoursEntity;
import entity.StakeholderEntity;
import exception.ExistException;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import session.stateless.BranchSessionBean;
import session.stateless.SystemMessagesBean;
import util.enumeration.CuisineType;
import util.enumeration.OperatingDay;
import util.enumeration.OperatingHours;
import util.enumhelper.OperatingHrs;
import util.localization.WebLocalization;

@ManagedBean
@ViewScoped
public class AddBranchManagedBean implements Serializable {

    @EJB
    private BranchSessionBean branchSessionBean;
    //Exception
    @EJB
    private SystemMessagesBean systemMessages;
    //User Selected Locale
    private String preferredLocale;
    private WebLocalization localization;
    private FnBBranchEntity fnbBranch;
    private OperatingDay[] operatingDay = OperatingDay.values();
    private OperatingDay normalOperatingDay;
    private OperatingHours openingHours;
    private OperatingHours closingHours;
    private OperatingHours extendedTimeStart;
    private OperatingHours extendedTimeEnd;
    private List<OperatingHrs> operatingHrsList;
    private List<OperatingHrs> extendedOperatingHoursList;
    private List<CuisineType> cuisineTypeList = null;
    private Date extendedCalendarDate;
    private boolean branchAdded;
    private String fnbType;
    private String operatingHoursRemarks;
    //for retrieving stakeholder
    private Long stakeholderId;
    private StakeholderEntity stakeholder;
    private boolean skip;

    public AddBranchManagedBean() {
    }

    public boolean isBranchAdded() {
        return branchAdded;
    }

    public void setBranchAdded(boolean branchAdded) {
        this.branchAdded = branchAdded;
    }

    public BranchSessionBean getBranchSessionBean() {
        return branchSessionBean;
    }

    public void setBranchSessionBean(BranchSessionBean branchSessionBean) {
        this.branchSessionBean = branchSessionBean;
    }

    public String getFnbType() {
        return fnbType;
    }

    public void setFnbType(String fnbType) {
        this.fnbType = fnbType;
    }

    public WebLocalization getLocalization() {
        return localization;
    }

    public void setLocalization(WebLocalization localization) {
        this.localization = localization;
    }

    public OperatingDay[] getOperatingDay() {
        return operatingDay;
    }

    public void setOperatingDay(OperatingDay[] operatingDay) {
        this.operatingDay = operatingDay;
    }

    public String getPreferredLocale() {
        return preferredLocale;
    }

    public void setPreferredLocale(String preferredLocale) {
        this.preferredLocale = preferredLocale;
    }

    public StakeholderEntity getStakeholder() {
        return stakeholder;
    }

    public void setStakeholder(StakeholderEntity stakeholder) {
        this.stakeholder = stakeholder;
    }

    public SystemMessagesBean getSystemMessages() {
        return systemMessages;
    }

    public void setSystemMessages(SystemMessagesBean systemMessages) {
        this.systemMessages = systemMessages;
    }

    /***************************************************/
    /*************** GET SET METHODS *******************/
    /***************************************************/
    public FnBBranchEntity getFnbBranch() {
        return fnbBranch;
    }

    public void setFnbBranch(FnBBranchEntity fnbBranch) {
        this.fnbBranch = fnbBranch;
    }

    public OperatingHours getExtendedTimeStart() {
        return extendedTimeStart;
    }

    public void setExtendedTimeStart(OperatingHours extendedTimeStart) {
        this.extendedTimeStart = extendedTimeStart;
    }

    public OperatingHours getExtendedTimeEnd() {
        return extendedTimeEnd;
    }

    public void setExtendedTimeEnd(OperatingHours extendedTimeEnd) {
        this.extendedTimeEnd = extendedTimeEnd;
    }

    public List<OperatingHrs> getOperatingHrsList() {
        return operatingHrsList;
    }

    public void setOperatingHrsList(List<OperatingHrs> operatingHrsList) {
        this.operatingHrsList = operatingHrsList;
    }

    public List<OperatingHrs> getExtendedOperatingHoursList() {
        return extendedOperatingHoursList;
    }

    public void setExtendedOperatingHoursList(List<OperatingHrs> extendedOperatingHoursList) {
        this.extendedOperatingHoursList = extendedOperatingHoursList;
    }

    public List<CuisineType> getCuisineTypeList() {
        return cuisineTypeList;
    }

    public void setCuisineTypeList(List<CuisineType> cuisineTypeList) {
        this.cuisineTypeList = cuisineTypeList;
    }

    public Date getExtendedCalendarDate() {
        return extendedCalendarDate;
    }

    public void setExtendedCalendarDate(Date extendedCalendarDate) {
        this.extendedCalendarDate = extendedCalendarDate;
    }

    public String getOperatingHoursRemarks() {
        return operatingHoursRemarks;
    }

    public void setOperatingHoursRemarks(String operatingHoursRemarks) {
        this.operatingHoursRemarks = operatingHoursRemarks;
    }

    public Long getStakeholderId() {
        return stakeholderId;
    }

    public void setStakeholderId(Long stakeholderId) {
        this.stakeholderId = stakeholderId;
    }

    public OperatingHours getOpeningHours() {
        return openingHours;
    }

    public void setOpeningHours(OperatingHours openingHours) {
        this.openingHours = openingHours;
    }

    public OperatingHours getClosingHours() {
        return closingHours;
    }

    public void setClosingHours(OperatingHours closingHours) {
        this.closingHours = closingHours;
    }

    public OperatingDay getNormalOperatingDay() {
        return normalOperatingDay;
    }

    public void setNormalOperatingDay(OperatingDay normalOperatingDay) {
        this.normalOperatingDay = normalOperatingDay;
    }

    /************************************************************************************\
    /*********************************** METHODS ****************************************\
    /************************************************************************************/
    public void initView(PhaseEvent event) {
        /*LOCALIZATION */
        localization = new WebLocalization();
        preferredLocale = localization.getPreferredLocaleFromSession();
        /* END LOCALIZATION */

        FacesContext.getCurrentInstance().getExternalContext().getSession(true);

        //Clear previous set messages(delete)
        FacesContext.getCurrentInstance().getExternalContext().getFlash().clear();

        stakeholderId = (Long) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholderId");
        if (stakeholderId == null) {
            //Session not save. (redirect Stakeholder to login.
            String nextPage = FacesContext.getCurrentInstance().getExternalContext().encodeActionURL(FacesContext.getCurrentInstance().getApplication().getViewHandler().getActionURL(FacesContext.getCurrentInstance(), "/StakeholderLogin.xhtml"));
            try {
                FacesContext.getCurrentInstance().getExternalContext().redirect(nextPage);
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        } else {

            if (stakeholder == null) {
                stakeholder = (StakeholderEntity) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("stakeholderEntity");

            }
            if (getFnbBranch() == null) {
                fnbBranch = new FnBBranchEntity();
                fnbBranch.setBranchAddress(new AddressEntity());

                this.extendedOperatingHoursList = new ArrayList<OperatingHrs>();
                this.cuisineTypeList = new ArrayList<CuisineType>();
                this.operatingHrsList = new ArrayList<OperatingHrs>();
            }
        }
    }//end of method init

    /* public String onFlowProcess(FlowEvent event) {  
    System.out.println("Current wizard step:" + event.getOldStep());  
    System.out.println("Next step:" + event.getNewStep());  
    
    if(isSkip()) {  
    setSkip(false);   //reset in case user goes back  
    return "confirm";  
    }  
    else {  
    return event.getNewStep();  
    }  
    } */
    //Add operating hours
    public void addOperatingHours() {
        OperatingHrs operatingHours = new OperatingHrs();
        boolean duplicate = false;

        if (openingHours.getTime().equals(closingHours.getTime())
                && !(openingHours.getLabel().equals("OFF") && closingHours.getLabel().equals("OFF"))) {
            String statusMessage = systemMessages.getSystemMessage("START_TIME_END_TIME_MUST_BE_DIFFERENT", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
        } else if ((openingHours.getLabel().equals("OFF") && !(closingHours.getLabel().equals("OFF")))
                || (!(openingHours.getLabel().equals("OFF")) && closingHours.getLabel().equals("OFF"))) {
            String statusMessage = systemMessages.getSystemMessage("START_TIME_END_TIME_MUST_BE_OFF", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
        } else if (openingHours.getTime().after(closingHours.getTime())) {
            String statusMessage = systemMessages.getSystemMessage("START_TIME_MUST_BE_BEFORE_END_TIME", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
        } // if all goes well....
        else {
            operatingHours.setOperatingDay(normalOperatingDay.getLabel());
            operatingHours.setOperatingDayEnum(normalOperatingDay);
            operatingHours.setClosingHours(closingHours.getTime());
            operatingHours.setClosingHoursEnum(closingHours);
            operatingHours.setOpeningHours(openingHours.getTime());
            operatingHours.setOpeningHoursEnum(openingHours);
            //operatingHours = new OperatingHrs(normalOperatingDay, normalOperatingDay.getLabel(), openingHours, openingHours.getTime(), closingHours, closingHours.getTime());
            //If there is no record exist in the list, add to arraylist
            if (operatingHrsList.isEmpty()) {
                operatingHrsList.add(operatingHours);
                String statusMessage = systemMessages.getSystemMessage("ADDED_TO_LIST", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, statusMessage));
            } else {
                //traverse array list to search for duplicate record
                //if exists, set msg and break from loop
                for (int i = 0; i < operatingHrsList.size(); i++) {
                    //Check both dates is equal
                    if (operatingHrsList.get(i).getOperatingDayEnum().equals(operatingHours.getOperatingDayEnum())
                            && (((operatingHours.getOpeningHours().after(operatingHrsList.get(i).getOpeningHours()) && operatingHours.getOpeningHours().before(operatingHrsList.get(i).getClosingHours()))
                            || (operatingHours.getClosingHours().after(operatingHrsList.get(i).getOpeningHours()) && operatingHours.getClosingHours().before(operatingHrsList.get(i).getClosingHours())))
                            || (operatingHours.getOpeningHours().equals(operatingHrsList.get(i).getOpeningHours()) && operatingHours.getClosingHours().equals(operatingHrsList.get(i).getClosingHours())))) {
                        //if all true, return duplicate msg
                        String statusMessage = systemMessages.getSystemMessage("DUPLICATE_TIME", preferredLocale);
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                        duplicate = true;
                        break;
                    }
                }

                //if there's no duplicate records in arraylist, add new record into list
                if (duplicate == false) {
                    for (int i = 0; i < operatingHrsList.size(); i++) {
                        if (i != (operatingHrsList.size() - 1)) { //not the last value in the list
                            if (operatingHours.getOperatingDayEnum().getDay() < operatingHrsList.get(i).getOperatingDayEnum().getDay()) {
                                operatingHrsList.add(i, operatingHours);
                                break;
                            } else if (operatingHours.getOperatingDayEnum().getDay() >= operatingHrsList.get(i).getOperatingDayEnum().getDay()
                                    && operatingHours.getOperatingDayEnum().getDay() < operatingHrsList.get(i + 1).getOperatingDayEnum().getDay()) {
                                if (operatingHours.getClosingHours().before(operatingHrsList.get(i).getOpeningHours()) || operatingHours.getClosingHours().equals(operatingHrsList.get(i).getOpeningHours())) {
                                    operatingHrsList.add(i, operatingHours);
                                } else {
                                    operatingHrsList.add(i + 1, operatingHours);
                                }
                                break;
                            }
                        } else if (operatingHours.getOperatingDayEnum().getDay() >= operatingHrsList.get(i).getOperatingDayEnum().getDay()
                                && ((operatingHrsList.size() - 1) == i)) {
                            if (operatingHours.getClosingHours().before(operatingHrsList.get(i).getOpeningHours()) || operatingHours.getClosingHours().equals(operatingHrsList.get(i).getOpeningHours())) {
                                operatingHrsList.add(i, operatingHours);
                            } else {
                                operatingHrsList.add(i + 1, operatingHours);
                            }
                            break;
                        } else if (operatingHrsList.size() == 1) { //if 1 record exist, check the date and add according to the day
                            if (operatingHours.getOperatingDayEnum().getDay() < operatingHrsList.get(0).getOperatingDayEnum().getDay()) {
                                operatingHrsList.add(0, operatingHours);
                                break;
                            } else if (operatingHours.getOperatingDayEnum().getDay() > operatingHrsList.get(0).getOperatingDayEnum().getDay()) {
                                operatingHrsList.add(operatingHours);
                                break;
                            } else {
                                if (operatingHours.getClosingHours().before(operatingHrsList.get(i).getOpeningHours()) || operatingHours.getClosingHours().equals(operatingHrsList.get(i).getOpeningHours())) {
                                    operatingHrsList.add(0, operatingHours);
                                } else {
                                    operatingHrsList.add(operatingHours);
                                }
                                break;
                            }
                        } else {
                            operatingHrsList.add(operatingHours);
                            break;
                        }
                    }
                    String statusMessage = systemMessages.getSystemMessage("ADDED_TO_LIST", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, statusMessage));
                }
            }
        }
    }

    /*Remove a specific date list from the datatable*/
    public void removeOperatingHoursList(OperatingHrs operatingHours) {
        operatingHrsList.remove(operatingHours);
        String statusMessage = systemMessages.getSystemMessage("REMOVED_FROM_LIST", preferredLocale);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, statusMessage));
    }

    //Add a specific date list for extended operating hours
    public void addSpecificDateList() {
        OperatingHrs specificOperatingHrs = new OperatingHrs();
        boolean duplicate = false;

        //Check calendar date is empty or not
        if (extendedCalendarDate != null) {
            Date todayDate = new Date();
            //entered calendar date has to be after today's date
            if (extendedCalendarDate.before(todayDate) && !(extendedCalendarDate.equals(todayDate))) {
                String statusMessage = systemMessages.getSystemMessage("EXTENDED_DATE_NOT_BEFORE_TODAY'S_DATE", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
            } else {
                //check whether the time entered is equal except for off
                if (extendedTimeStart.getTime().equals(extendedTimeEnd.getTime())
                        && !(extendedTimeStart.getLabel().equals("OFF") && extendedTimeEnd.getLabel().equals("OFF"))) {
                    String statusMessage = systemMessages.getSystemMessage("EXTENDED_START_TIME_END_TIME_MUST_BE_DIFFERENT", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                } /*else if (extendedTimeStart.getTime().after(extendedTimeEnd.getTime())
                && (!(extendedTimeStart.getLabel().equals("OFF") && !(extendedTimeEnd.getLabel().equals("OFF"))))) {
                //String statusMessage = systemMessages.getSystemMessage("CREATION_SUCCESS", selectedLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, "Extended Operating Hours: Select an appropriate time range", "Extended Operating Hours: Select an appropriate time range"));
                } */ //check if 1 time is entered off, the other must also be off
                else if ((extendedTimeStart.getLabel().equals("OFF") && !(extendedTimeEnd.getLabel().equals("OFF")))
                        || (!(extendedTimeStart.getLabel().equals("OFF")) && extendedTimeEnd.getLabel().equals("OFF"))) {
                    String statusMessage = systemMessages.getSystemMessage("EXTENDED_START_TIME_END_TIME_MUST_BE_OFF", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                } // if all goes well....
                else {
                    //Select the day string value from enum(Compare calendar day(int value) to enum day(int value))
                    for (int i = 0; i < operatingDay.length; i++) {
                        if (extendedCalendarDate.getDay() == operatingDay[i].getDay()) {
                            String day = operatingDay[i].getLabel();
                            specificOperatingHrs = new OperatingHrs(operatingDay[i], day, extendedTimeStart, extendedTimeStart.getTime(), extendedTimeEnd, extendedTimeEnd.getTime(), extendedCalendarDate);
                        }
                    }
                    //If there is no record exist in the list, add to arraylist
                    if (extendedOperatingHoursList.isEmpty()) {
                        extendedOperatingHoursList.add(specificOperatingHrs);
                        String statusMessage = systemMessages.getSystemMessage("ADDED_TO_LIST", preferredLocale);
                        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, statusMessage));
                    } else {
                        //traverse array list to search for duplicate record
                        //if exists, set msg and break from loop
                        for (int i = 0; i < extendedOperatingHoursList.size(); i++) {
                            //Check both dates is equal
                            if (extendedOperatingHoursList.get(i).getSpecificDate().equals(specificOperatingHrs.getSpecificDate())
                                    && ( //check new opening time has to be after closing time
                                    (extendedOperatingHoursList.get(i).getClosingHours().after(specificOperatingHrs.getOpeningHours()))
                                    || //check both opening n closing is equal
                                    (extendedOperatingHoursList.get(i).getOpeningHours().equals(specificOperatingHrs.getOpeningHours())
                                    && extendedOperatingHoursList.get(i).getClosingHours().equals(specificOperatingHrs.getClosingHours())))) {
                                //if all true, return duplicate msg
                                String statusMessage = systemMessages.getSystemMessage("DUPLICATE_DATE", preferredLocale);
                                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                                duplicate = true;
                                break;
                            }
                        }
                        //if there's no duplicate records in arraylist, add new record into list
                        if (duplicate == false) {
                            extendedOperatingHoursList.add(specificOperatingHrs);
                            String statusMessage = systemMessages.getSystemMessage("ADDED_TO_LIST", preferredLocale);
                            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, statusMessage));
                        }
                    }
                }
            }
        } else {
            String statusMessage = systemMessages.getSystemMessage("EXTENDED_IS_NOT_SELECTED", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
        }
    }


    /*Remove a specific date list from the datatable*/
    public void removeSpecificDateList(OperatingHrs extendedOperatingHrs) {
        extendedOperatingHoursList.remove(extendedOperatingHrs);
        String statusMessage = systemMessages.getSystemMessage("REMOVED_FROM_LIST", preferredLocale);
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, statusMessage));
    }

    /*Save New Branch*/
    public void saveNewBranch() {
        if (checkOperatingDayList() == true) { //if all operating days are being selected
            try {
                branchAdded = branchSessionBean.addBranch(getFnbBranch().getBranchName(), getFnbBranch().getBranchAddress().getPostalCode(), getFnbBranch().getBranchAddress().getUnitNumber(), getFnbBranch().getBranchAddress().getBlkNumber(),
                        getFnbBranch().getBranchAddress().getStreetName(), getFnbBranch().getBranchAddress().getBuildingName(), getFnbBranch().getContactNumber(), getFnbBranch().getContactPerson(),
                        getFnbBranch().getEmailAddress(), getFnbBranch().getFnBType(), getFnbBranch().getIsHalal(), getFnbBranch().getPriceRange(),
                        preferredLocale, operatingHoursRemarks, getCuisineTypeList(), operatingHrsList, getExtendedOperatingHoursList(), stakeholder);

                if (branchAdded == true) {
                    String statusMessage = systemMessages.getSystemMessage("BRANCH_CREATION_SUCCESS", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, statusMessage, ""));
                    reset();
                } else {
                    String statusMessage = systemMessages.getSystemMessage("BRANCH_CREATION_UNSUCCESSFUL", preferredLocale);
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, ""));
                }
            } catch (ExistException ex) {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, ex.getMessage(), ""));
            }
        }
    }

    /*Reset the values of all the fields after adding into the database*/
    public void reset() {
        fnbBranch = new FnBBranchEntity();
        fnbBranch.setBranchAddress(new AddressEntity());
        setOperatingHoursRemarks("");
        cuisineTypeList.clear();
        setOpeningHours(OperatingHours.EightAM);
        setClosingHours(OperatingHours.EightAM);
        setExtendedCalendarDate(null);
        setExtendedTimeStart(OperatingHours.EightAM);
        setExtendedTimeEnd(OperatingHours.EightAM);
        operatingHrsList.clear();
        extendedOperatingHoursList.clear();
    }

    public boolean checkOperatingDayList() {
        List<OperatingDay> listOfMissingDays = new ArrayList<OperatingDay>();
        if (!operatingHrsList.isEmpty()) {
            listOfMissingDays.add(operatingHrsList.get(0).getOperatingDayEnum());
            for (int i = 0; i < operatingHrsList.size(); i++) {
                if (!listOfMissingDays.contains(operatingHrsList.get(i).getOperatingDayEnum())) {
                    listOfMissingDays.add(operatingHrsList.get(i).getOperatingDayEnum()); //add all the non duplicated day into missing day list
                }
            }
            if (listOfMissingDays.size() < 7) { //if there is any missing days
                String monday, tuesday, wednesday, thursday, friday, sat, sun;
                String statusMessage = systemMessages.getSystemMessage("BRANCH_OPERATING_DAYS", preferredLocale);
                if (!listOfMissingDays.contains(OperatingDay.MONDAY)) {
                    //listOfMissingDays.remove(OperatingDay.MONDAY); //remove MONDAY from list if exist
                    monday = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_MONDAY", preferredLocale);
                    statusMessage += monday + " ";
                }
                if (!listOfMissingDays.contains(OperatingDay.TUESDAY)) {
                    //listOfMissingDays.remove(OperatingDay.TUESDAY); //remove TUESDAY from list if exist
                    tuesday = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_TUESDAY", preferredLocale);
                    statusMessage += tuesday + " ";
                }
                if (!listOfMissingDays.contains(OperatingDay.WEDNESDAY)) {
                    //listOfMissingDays.remove(OperatingDay.WEDNESDAY); //remove WEDNESDAY from list if exist
                    wednesday = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_WEDNESDAY", preferredLocale);
                    statusMessage += wednesday + " ";
                }
                if (!listOfMissingDays.contains(OperatingDay.THURSDAY)) {
                    //listOfMissingDays.remove(OperatingDay.THURSDAY); //remove THURSDAY from list if exist
                    thursday = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_THURSDAY", preferredLocale);
                    statusMessage += thursday + " ";
                }
                if (!listOfMissingDays.contains(OperatingDay.FRIDAY)) {
                    //listOfMissingDays.remove(OperatingDay.FRIDAY); //remove FRIDAY from list if exist
                    friday = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_FRIDAY", preferredLocale);
                    statusMessage += friday + " ";
                }
                if (!listOfMissingDays.contains(OperatingDay.SATURDAY)) {
                    //listOfMissingDays.remove(OperatingDay.SATURDAY); //remove SATURDAY from list if exist
                    sat = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_SATURDAY", preferredLocale);
                    statusMessage += sat + " ";
                }
                if (!listOfMissingDays.contains(OperatingDay.SUNDAY)) {
                    //listOfMissingDays.remove(OperatingDay.SUNDAY); //remove SUNDAY from list if exist
                    sun = systemMessages.getSystemMessage("BRANCH_OPERATINGDAYS_SUNDAY", preferredLocale);
                    statusMessage += sun + " ";
                }

                statusMessage += systemMessages.getSystemMessage("IS_NOT_SELECTED", preferredLocale);
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
                return false;
            }
        } else {
            String statusMessage = systemMessages.getSystemMessage("OPERATING_HOURS_ARE_SELECTED", preferredLocale);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage));
            return false;
        }
        return true; //if all 7 days are included in the list, clear the list and return it empty to indicate no missing days
    }

    /************************************************************************************|
    |*********************************** VALIDATION METHODS *****************************|
    |************************************************************************************/
    public void validateOperatingHours(FacesContext context, UIComponent component, Object value) {
        //Get the specific component ID
        String ID = component.getId();
        //Get the end time of the operating hours
        OperatingHours endTime = (OperatingHours) value;
        //Check the component ID
        if (ID.contains("Monday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Tuesday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Wednesday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Thursday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Friday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Saturday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        } else if (ID.contains("Sunday")) {
            String msg = validateOpHrs(component, endTime);
            //if message is not empty, display.
            if (!msg.isEmpty()) {
                FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg);
                context.addMessage(component.getClientId(context), message);
            }
        }
    }

    public String validateOpHrs(UIComponent component, OperatingHours endTime) {
        UIInput day = (UIInput) component.getAttributes().get("day");
        OperatingHours startTime = (OperatingHours) day.getValue();

        //If either start time of end time is off
        if (startTime.getLabel().equals("OFF") || endTime.getLabel().equals("OFF")) {
            //if confirm both is off
            if (startTime.getLabel().equals("OFF") && endTime.getLabel().equals("OFF")) {
                return "";
            } else {
                //set the component that value is deemed incorrect to false to disallow submitting of page
                ((UIInput) component).setValid(false);
                //return error message
                String statusMessage = systemMessages.getSystemMessage("OPERATING_HOURS_START_TIME_END_TIME_MUST_BE_OFF", preferredLocale);
                return statusMessage;
            }
        } else if (startTime.getTime().equals(endTime.getTime())) {
            //set the component that value is deemed incorrect to false to disallow submitting of page
            ((UIInput) component).setValid(false);
            //return error message
            String statusMessage = systemMessages.getSystemMessage("OPERATING_HOURS_START_TIME_END_TIME_MUST_BE_DIFFERENT", preferredLocale);
            return statusMessage;
        }
        return "";
    }

    public void validateEmail(FacesContext context, UIComponent toValidate, Object value) {
        String email = (String) value;
        Pattern p = Pattern.compile("^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");

        //Match the given string with the pattern
        Matcher m = p.matcher(email);

        //Check whether match is found
        boolean matchFound = m.matches();

        //if mail does not match the pattern
        if (!matchFound) {
            ((UIInput) toValidate).setValid(false);
            String statusMessage = systemMessages.getSystemMessage("INVALID_EMAIL_ADDRESS", preferredLocale);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage);
            context.addMessage(toValidate.getClientId(context), message);
        }
    }

    public void validateBranchName(FacesContext context, UIComponent toValidate, Object value) {
        String name = (String) value;
        if (!branchSessionBean.validateBranchName(name)) {
            ((UIInput) toValidate).setValid(false);
            String statusMessage = systemMessages.getSystemMessage("BRANCH_NAME_EXISTS", preferredLocale);
            FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_ERROR, statusMessage, statusMessage);
            context.addMessage(toValidate.getClientId(context), message);
        }
    }
    /*
    /**
     * @return the skip
    
    public boolean isSkip() {
    return skip;
    }
    
    /**
     * @param skip the skip to set
    
    public void setSkip(boolean skip) {
    this.skip = skip;
    }
     */
}
